package com.zcxy.fast.service.impl;


import cn.hutool.core.date.DateUtil;
import com.zcxy.fast.entity.SysConfig;
import com.zcxy.fast.exception.BusinessException;
import com.zcxy.fast.service.IGenHelperService;
import com.zcxy.fast.service.ISysAutocodeService;
import com.zcxy.fast.util.AutoUtils;
import com.zcxy.fast.utils.StringUtils;
import com.zcxy.fast.vo.SysAutocodeVo;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 * 用户 Service接口
 *
 * @author zcc
 * @email 860474958@qq.com
 * @date 2020-06-01
 */
@Service
public class GenHelperServiceImpl implements IGenHelperService {

    @Autowired
    private ISysAutocodeService iSysAutocodeService;


    @Override
    public void  genCode(SysAutocodeVo sysAutocodeVo, HttpServletResponse response) {

        Properties prop = new Properties();
        prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        Velocity.init(prop);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);

        //如果当前生成的是主附表
        if ("4".equals(sysAutocodeVo.getRelationType())) {
            //需要再次处理附表相关数据
            String childTable = sysAutocodeVo.getChildTable();
            SysAutocodeVo sysAutocodeChildVo = iSysAutocodeService.viewSysAutocode(childTable);
            sysAutocodeChildVo.setChildTableKey(StringUtils.toCamelCase(sysAutocodeVo.getChildTableKey()));
            sysAutocodeVo.setChildTableModule(sysAutocodeChildVo.getComment());
            sysAutocodeVo.setChildClassNameS(sysAutocodeChildVo.getClassNameS());
            genOutputStream(zip, sysAutocodeVo);
            genOutputStream(zip, sysAutocodeChildVo);
        }else{
            genOutputStream(zip, sysAutocodeVo);
        }
        IOUtils.closeQuietly(zip);
        byte[] data=outputStream.toByteArray();
        response.setHeader("Content-Disposition", "attachment; filename=\"auto.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");

        try {
            IOUtils.write(data, response.getOutputStream());
        } catch (IOException var6) {
            var6.printStackTrace();
            IOUtils.closeQuietly(outputStream);
        }



    }

    public void genOutputStream( ZipOutputStream zip, SysAutocodeVo sysAutocodeVo) {
        Map<String, Object> map = new HashMap<>();
        map.put("time", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        SysConfig sysConfig = initSysconfig();
        map.put("sysConfig", sysConfig);
        map.put("main", sysAutocodeVo);
        map.put("items", sysAutocodeVo.getSysAutocodeItems());
        VelocityContext context = new VelocityContext(map);
        List<String> templates = AutoUtils.getTemplates(sysAutocodeVo.getRelationType());
        Iterator var8 = templates.iterator();

        while (var8.hasNext()) {
            String template = (String) var8.next();
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, "UTF-8");
            tpl.merge(context, sw);
            try {
                zip.putNextEntry(new ZipEntry(getFileName(template, sysConfig, sysAutocodeVo)));
                IOUtils.write(sw.toString(), zip, "UTF-8");
                zip.closeEntry();
                IOUtils.closeQuietly(sw);
            } catch (IOException var13) {
                throw new BusinessException("渲染模板失败，表名：" + sysAutocodeVo.getTableName(), new Object[]{var13});
            }
        }
    }



    public SysConfig  initSysconfig(){
        SysConfig sysConfig=new SysConfig();
        sysConfig.setEmail("860474958@qq.com");
        sysConfig.setAuthor("zcc");
        sysConfig.setBasePath("com.zcxy.fast");
        sysConfig.setPo("vo");
        sysConfig.setService("service");
        sysConfig.setServiceImpl("service.impl");
        sysConfig.setController("controller");
        sysConfig.setVue("vue");
        sysConfig.setVueApi("/fast/fast-platform");
        sysConfig.setEntity("entity");
        sysConfig.setVueApiPath("src.api.system");
        sysConfig.setVueTempPath("src.views.fast");
        sysConfig.setVueImportPath("/api/system");
        return sysConfig;
    }

    public   String getFileName(String template, SysConfig sysConfig,SysAutocodeVo sysAutocodeVo) {
        String allpath=sysConfig.getBasePath().replaceAll("\\.", Matcher.quoteReplacement(File.separator));
        String vueApiPath=sysConfig.getVueApiPath().replaceAll("\\.", Matcher.quoteReplacement(File.separator));
        String vueTempPath=sysConfig.getVueTempPath().replaceAll("\\.", Matcher.quoteReplacement(File.separator));

        if (template.contains("Entity.java.vm")) {
            return  allpath+ File.separator+sysConfig.getEntity().replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + File.separator + sysAutocodeVo.getClassName() + ".java";
        }else if(template.contains("EntityVo.java.vm")){
            return allpath+ File.separator+sysConfig.getPo().replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + File.separator + sysAutocodeVo.getClassName() + "Vo.java";
        }else if(template.contains("mapper.java.vm")){
            return allpath+ File.separator+"mapper" + File.separator + sysAutocodeVo.getClassName() + "Mapper.java";
        }else if(template.contains("service.java.vm")){
            return allpath+ File.separator+sysConfig.getService().replaceAll("\\.", Matcher.quoteReplacement(File.separator))  + File.separator +"I"+ sysAutocodeVo.getClassName() + "Service.java";
        }
        else if(template.contains("serviceImpl.java.vm")){
            return allpath+ File.separator+sysConfig.getServiceImpl().replaceAll("\\.", Matcher.quoteReplacement(File.separator))  + File.separator + sysAutocodeVo.getClassName() + "ServiceImpl.java";
        }
        else if(template.contains("controller.java.vm")){
            return allpath+ File.separator+sysConfig.getController().replaceAll("\\.", Matcher.quoteReplacement(File.separator))  + File.separator + sysAutocodeVo.getClassName() + "Controller.java";
        }
        else if(template.contains("api.js.vm")){
            return vueApiPath+ File.separator+ sysAutocodeVo.getClassNameS() + ".js";
        }
        else if(template.contains("local.js.vm")){
            return vueTempPath+ File.separator+ sysAutocodeVo.getClassNameS()+ File.separator+ "local.js";
        }
        else if(template.contains("index.vue.vm")){
            return vueTempPath+ File.separator+ sysAutocodeVo.getClassNameS()+ File.separator+ "index.vue";
        }
        else if(template.contains("tree.vue.vm")){
            return vueTempPath+ File.separator+ sysAutocodeVo.getClassNameS()+ File.separator+ "index.vue";
        }
        return "";
    }
}
